Win32 Programming: Processes and Threads

Revised: 03 March 2005
Windows Programming Contents

Web Resources:

Code Project Windows Forms Code Guru Win32, COM, MFC Windows Developer's Journal GotDotNet



A process is just a container for threads and their resources. These include:
  1. process code, including that for Dynamic Link Libraries, loaded at run-time
  2. global memory
  3. stack frames for each thread, containing local variables declared in their thread processing functions, and all the functions they call
  4. thread local storage
  5. process heaps
The process, its DLL modules, threads, heaps, and windows the threads create, are all referenced by handles. A handle is just an index into a table of addresses of each of the kernel objects the process has created.

Threads are either UI or worker threads. UI threads are those that create one or more windows, and each window has a message loop, responsible for extracting and processing messages enqueued by the operating system or code within the process. Each message represents some kind of event - perhaps a mouse movement or key press - that is relevant to the receiving window. When a UI thread creates a window, its thread local storage is used to hold state for that window. Many of the Win32 API functions devoted to windows processing use that information to carry out their assigned tasks.

For this reason, a worker thread (which does not hold the relevant window state) must never directly call Win32 API functions that take a window handle. That function will probably expect the calling thread to have the appropriate state for the window, which the worker thread does not have, and the resulting behavior is undefined. We say that:
Windows have thread afinity
That is, they should only be called by the thread that created them. When a worker thread needs to communicate with the processing function for a window, it does this by sending a message to the window using ::SendMessage(hWnd,Msg,wParm,lParm) or posting a message to its message queue using ::PostMessage(hWnd,Msg,wParm,lParm);